package org.example.consumer.component;

import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.checkerframework.checker.units.qual.C;
import org.example.service.AsyncService;
import org.example.service.ContextService;
import org.example.service.DemoService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Component
public class Task implements CommandLineRunner {
    @DubboReference
    private DemoService demoService;
    @DubboReference
    private AsyncService asyncService;
    @DubboReference
    private ContextService contextService;

    @Override
    public void run(String... args) throws Exception {
        String result = demoService.sayHello("world");
        System.out.println("Receive result ===> " + result);
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println(new Date() + " Receive result ===> " + demoService.sayHello("world"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
            }
        }).start();

        // 调用异步接口
        CompletableFuture<String> future1 = asyncService.asyncInvoke("async call request1");
        future1.whenComplete((v, t) -> {
            if (t != null) {
                t.printStackTrace();
            } else {
                System.out.println("AsyncTask Response-1: " + v);
            }
        });
        // 两次调用非顺序返回
        CompletableFuture<String> future2 = asyncService.asyncInvoke("async call request2");
        future2.whenComplete((v, t) -> {
            if (t != null) {
                t.printStackTrace();
            } else {
                System.out.println("AsyncTask Response-2: " + v);
            }
        });
        // consumer 异步调用
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            return asyncService.invoke("invoke call request3");
        });
        future3.whenComplete((v, t) -> {
            if (t != null) {
                t.printStackTrace();
            } else {
                System.out.println("AsyncTask Response-3: " + v);
            }
        });
        System.out.println("AsyncTask Executed before response return.");

        // 往服务端传递参数
        RpcContext.getClientAttachment().setAttachment("clientKey1", "clientValue1");
        String res = contextService.invoke("context1");
        // 接收传递回来参数
        Map<String, Object> clientAttachment = RpcContext.getServerContext().getObjectAttachments();
        System.out.println("ContextTask clientAttachment: " + JSON.toJSONString(clientAttachment));
        System.out.println("ContextService Return: " + res);
    }
}
